package org.az.netty_study.p11_netty的黏包与半包;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

/**
 * 前面介绍过nio的黏包和半包，在netty中也有这个问题，下面演示了这个问题
 * TCP/IP都有黏包和半包问题，UDP没有这个问题
 */
@Slf4j
public class _1_演示黏包半包 {
    public static void main(String[] args) {
        new Bootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<NioSocketChannel>() {

                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                            //连接建立后,会回调channel上的所有入站handler，并回调他们的channelActive方法发送数据
                            //使用前面的sync也可以在连接建立后发送数据
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                /**
                                 * 向服务端发送100条报文，每条16个字节
                                 * 按照常理来讲，服务端那边会读取100次，每次读取16个字节
                                 * 然而观察服务端日志，发现服务端一次读了1600个字节，这就是典型的黏包
                                 * 怎么观察半包现象呢？
                                 *   调小服务端接收缓冲区，再次发送就发现服务端每次接收到的的数据量都不一样，说明发生了半包现象
                                 */
                                for (int i = 0; i < 100; i++) {
                                    ByteBuf buf = ctx.alloc().buffer(10);
                                    buf.writeBytes(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'});
                                    ctx.writeAndFlush(buf);
                                }
                            }
                        });
                    }
                }).connect(new InetSocketAddress("localhost", 7777));

    }
}
